﻿using Minecraft.Config;
using Minecraft.Config.Csv.CsvCls;
using Minecraft.Model;
using Minecraft.Model.Backpack;
using Minecraft.Model.Blueprint;
using Minecraft.Model.ReqResp;
using SuperSocket.SocketBase.Command;
using SuperSocket.SocketBase.Protocol;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Minecraft.ServerHall.Cmd
{
	public class BlueprintMake : CommandBase<MinecraftSession, StringRequestInfo>
	{
		public override string Name
		{
			get
			{
				return ProtocolHelper.GetProtocolStr(defCommand);
			}
		}
		private EnumCommand defCommand = EnumCommand.Blueprint_BlueprintMake;
		public override void ExecuteCommand(MinecraftSession session, StringRequestInfo requestInfo)
		{
			var req = requestInfo.GetRequestObj<BlueprintMakeReq>(session);
			if (req == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：请求实体为空）" });
				return;
			}

			//if (JsonConfig.Value.IsDebug)
			//{
			//	req.blueprintId = session.minecraftSessionInfo.blueprint.GetBlueprintInfoList().FirstOrDefault().blueprintId;
			//}

			if (!session.minecraftSessionInfo.IsLogin)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：未登录）" });
				return;
			}
			if (req.blueprintId.IsNullOrWhiteSpace())
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：blueprintId参数为空）" });
				return;
			}
			//Mod_Blueprint mod_Blueprint = CsvConfig.blueprintList.FirstOrDefault(m => m.Id == req.blueprintId);
			Mod_Blueprint mod_Blueprint = CsvConfig.GetMod_BlueprintInfoById(req.blueprintId);
			if (mod_Blueprint == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：配置表 mod_Blueprint 信息为空）" });
				return;
			}

			var blueprintInfo = session.minecraftSessionInfo.blueprint.GetBlueprintInfoList().FirstOrDefault(m => m.blueprintId == req.blueprintId);
			if (blueprintInfo == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误1：（原因：内存中 blueprintInfo 信息为空）" });
				return;
			}
			if (!blueprintInfo.isStudied)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：该蓝图Id【{blueprintInfo.blueprintId}】还未学习）" });
				return;
			}

			//判断是否满足制造条件，背包中配方材料是否足够
			//Mod_Compositing mod_Compositing = CsvConfig.compositingList.FirstOrDefault(m => m.Id == mod_Blueprint.Recipe_id);
			Mod_Compositing mod_Compositing = CsvConfig.GetMod_CompositingInfoById(mod_Blueprint.Recipe_id);
			if (mod_Compositing == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：配置表中mod_Compositing 不存在该信息）" });
				return;
			}
			//Mod_Items mod_Items = CsvConfig.itemsList.FirstOrDefault(m => m.Id == req.blueprintId);
			Mod_Items mod_Items = CsvConfig.GetMod_ItemsInfoById(mod_Compositing.Product);
			if (mod_Items == null)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：配置表中产物 mod_Items 不存在该信息）" });
				return;
			}

			session.IsBackpackFull(out BaseResp baseResp, out bool isFull, out List<BackpackGoodsItemInfo> canPlacedBpCellInfoList);
			if (baseResp.RespLevel != RespLevelEnum.Success)
			{
				session.Send(defCommand, req, baseResp);
				return;
			}
			if (isFull)
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：背包满了）" });
				return;
			}

			var backpackGoodsList = session.minecraftSessionInfo.goodsList.Where(m => MinecraftConfig.bpShortbarBelongsToTypeList.Any(k => k == m.enumGoodsBelongsToType_Convert) && m.guid == "").ToList();
			if (backpackGoodsList == null || !backpackGoodsList.Any())
			{
				session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：背包物品为空）" });
				return;
			}
			Dictionary<string, int> dict = new Dictionary<string, int>(); //保存现有材料的个数
			List<string> itemIdList = new List<string>(); //材料的itemId
			bool isEnough = true;
			foreach (var modRecipeInfo in mod_Compositing.modRecipeInfoList_Convert)
			{
				var count = backpackGoodsList.Where(m => m.GoodsItemId == modRecipeInfo.GoodsItemId).Sum(m => m.Num);
				dict.Add(modRecipeInfo.GoodsItemId, count);
				itemIdList.Add(modRecipeInfo.GoodsItemId);
				if (count < modRecipeInfo.Num)
				{
					isEnough = false;
				}
			}
			//添加操作影响的positionOptList
			List<BackpackGoodsPositionOpt> positionOptList = new List<BackpackGoodsPositionOpt>();
			if (isEnough)
			{
				//从配置中读取指定物品存放数量上限
				var goodsItemMaxNum = session.GetMaxCellNumConvert(mod_Items.Id);
				//加载背包物品goodsItem信息
				List<BackpackGoodsItemInfo> goodsItemInfoList = session.GetBackpackGoodsItemInfoList(EnumGoodsBelongsToType.Backpack, "", out baseResp);
				if (baseResp.RespLevel != RespLevelEnum.Success)
				{
					session.Send(defCommand, req, baseResp);
					return;
				}

				var curGoodsItemItemInfo = goodsItemInfoList.FirstOrDefault(m => m.GoodsNum <= 0 || m.GoodsNum > 0 && m.GoodsNum < goodsItemMaxNum && m.GoodsItemId == mod_Items.Id);
				if (curGoodsItemItemInfo == null)
				{
					session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误9（原因：背包已经满了，无法制造）" });
					return;
				}
				var backpackGoodsItemInfo = canPlacedBpCellInfoList.FirstOrDefault(m => m.GoodsNum <= 0 || m.GoodsItemId == mod_Items.Id && m.GoodsNum > 0);
				if (backpackGoodsItemInfo == null)
				{
					session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "错误9（原因：背包数据出错，没有可以存放产物的格子）" });
					return;
				}
				var goodsInfo = session.minecraftSessionInfo.goodsList.FirstOrDefault(m => m.enumGoodsBelongsToType_Convert == backpackGoodsItemInfo.enumGoodsBelongsToType && m.GoodsPosition == backpackGoodsItemInfo.GoodsPosition && m.guid == backpackGoodsItemInfo.guid);
				if (goodsInfo == null)
				{
					goodsInfo = new GoodsModel
					{
						BelongsTo = (int)curGoodsItemItemInfo.enumGoodsBelongsToType,
						GoodsId = StringHelper.GetGuidStr(),
						GoodsItemId = mod_Items.Id,
						GoodsPosition = curGoodsItemItemInfo.GoodsPosition,
						PlayerId = session.minecraftSessionInfo.player.PlayerId,
						WastageValue = 100,
						Num = 1,
						guid = backpackGoodsItemInfo.guid,
					};
					//添加上新制造的物品
					session.minecraftSessionInfo.goodsList.Add(goodsInfo);
				}
				else
				{
					goodsInfo.Num++;
				}
				if (!positionOptList.Any(m => m.enumGoodsBelongsToType == goodsInfo.enumGoodsBelongsToType_Convert && m.GoodsPosition == goodsInfo.GoodsPosition && m.guid == goodsInfo.guid))
				{
					positionOptList.Add(new BackpackGoodsPositionOpt
					{
						enumGoodsBelongsToType = goodsInfo.enumGoodsBelongsToType_Convert,
						GoodsPosition = goodsInfo.GoodsPosition,
						guid = goodsInfo.guid
					});
				}

				foreach (var itemId in itemIdList)
				{
					var modRecipeInfo = mod_Compositing.modRecipeInfoList_Convert.FirstOrDefault(m => m.GoodsItemId == itemId);
					if (modRecipeInfo == null)
					{
						session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：服务器判断错误：modRecipeInfo为空）" });
						return;
					}
					int n = modRecipeInfo.Num;
					while (true)
					{
						var backpackGoodsInfo = backpackGoodsList.FirstOrDefault(m => m.GoodsItemId == itemId && m.Num > 0);
						if (backpackGoodsInfo == null)
						{
							break;
						}
						if (!positionOptList.Any(m => m.enumGoodsBelongsToType == backpackGoodsInfo.enumGoodsBelongsToType_Convert && m.GoodsPosition == backpackGoodsInfo.GoodsPosition && m.guid == backpackGoodsInfo.guid))
						{
							positionOptList.Add(new BackpackGoodsPositionOpt
							{
								enumGoodsBelongsToType = backpackGoodsInfo.enumGoodsBelongsToType_Convert,
								GoodsPosition = backpackGoodsInfo.GoodsPosition,
								guid = backpackGoodsInfo.guid
							});
						}
						if (backpackGoodsInfo.Num >= n)
						{
							backpackGoodsInfo.Num -= n;
							break;
						}
						else
						{
							backpackGoodsInfo.Num = 0;
							n -= modRecipeInfo.Num;
						}
					}

					////获取背包中已有的材料列表
					//var list = backpackGoodsList.Where(m => m.GoodsItemId == itemId).Take(modRecipeInfo.Num).ToList();
					//foreach (var goodsInfo in list)
					//{
					//	//移除背包中用过的材料
					//	session.minecraftSessionInfo.goodsList.RemoveAll(m => m.GoodsId == goodsInfo.GoodsId);
					//}


					dict[itemId] -= modRecipeInfo.Num;
					//var l = list.GetBackpackGoodsCellInfo();
					//foreach (var item in l)
					//{
					//	if (!positionOptList.Any(m => m.enumGoodsBelongsToType == item.enumGoodsBelongsToType && m.GoodsPosition == item.GoodsPosition))
					//	{
					//		positionOptList.Add(new BackpackGoodsPositionOpt
					//		{
					//			enumGoodsBelongsToType = item.enumGoodsBelongsToType,
					//			GoodsPosition = item.GoodsPosition
					//		});
					//	}
					//}
				}
				if (!positionOptList.Any())
				{
					session.Send(defCommand, req, new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：positionOptList 元素个数为空）" });
					return;
				}
			}

			List<BlueprintRemainMaterialInfo> blueprintRemainMaterialInfoList = new List<BlueprintRemainMaterialInfo>();
			foreach (var item in dict)
			{
				blueprintRemainMaterialInfoList.Add(new BlueprintRemainMaterialInfo
				{
					goodsItemId = item.Key,
					remainNum = item.Value
				});
			}

			//找到受影响的物品位置信息
			Func<GoodsModel, bool> predicateBeAffected = m =>
				positionOptList.Any(n => n.enumGoodsBelongsToType == m.enumGoodsBelongsToType_Convert
				&& n.GoodsPosition == m.GoodsPosition);
			var posGoodsinfoList = session.minecraftSessionInfo.goodsList.Where(predicateBeAffected).GetBackpackGoodsCellInfo();

			session.minecraftSessionInfo.goodsList.RemoveAll(m => m.Num <= 0);

			var resp = new BlueprintMakeResp
			{
				blueprintId = req.blueprintId,
				isMaterialEnough = isEnough,
				blueprintRemainMaterialInfoList = blueprintRemainMaterialInfoList,
				backpackCellInfoList = posGoodsinfoList
			};
			session.Send(defCommand, req, resp);
		}
	}
}
